import smbus
import time
from config import *

bus = smbus.SMBus(MCP23017_ID)

# 对寄存器的数据进行初始化
for addr in range(22):
    if (addr == 0) or (addr == 1):
        bus.write_byte_data(MCP23017_ADDRESS, addr, 0xFF)
    else:
        bus.write_byte_data(MCP23017_ADDRESS, addr, 0x00)

# MCP23017对应LCD1602的输出输入
# MCP23017GP -- LCD1602  -- in/out
# B7         -- RS       -- out
# B6         -- RW       -- out
# B5         -- E        -- out
# B4-B1      -- D4-D7    -- out
# B0         -- G        -- out
# A7         -- B        -- out
# A6         -- R        -- out
# A5         -- K        -- out
# A4-A0      -- keyboard -- in

# 设置B7-B0输出
bus.write_byte_data(MCP23017_ADDRESS,MCP23017_IODIRB,0x00)
    
# 设置A7-A5输出，A4-A0输入
bus.write_byte_data(MCP23017_ADDRESS,MCP23017_IODIRA,0x1F)
bus.write_byte_data(MCP23017_ADDRESS,MCP23017_GPPUA,0x1F)

print("----------------设置输入输出完毕----------------")

def send_bit8(bits:int, mode:str)->None:
    if mode == "data":
      	write_mask = WRITE_DATA_MASK
    elif mode == "cmd":
      	write_mask = WRITE_CMD_MASK
    else:
        return None
    # 数据倒位
    bits = DRMAP[bits//16]*16+DRMAP[bits%16]
    # 输送B高4位
    buf = (bits >> 3) & DATA_MASK
    buf |= write_mask | LIGHT_G     # RS = 0, RW = 0, EN = 1
    bus.write_byte_data(MCP23017_ADDRESS, MCP23017_GPIOB, buf)
    time.sleep(0.002)
    buf &= WRITE_EN       # Make EN = 0
    bus.write_byte_data(MCP23017_ADDRESS, MCP23017_GPIOB, buf)
    # 输送B低4位
    buf = (bits << 1) & DATA_MASK
    buf |= write_mask | LIGHT_G     # RS = 0, RW = 0, EN = 1
    bus.write_byte_data(MCP23017_ADDRESS, MCP23017_GPIOB, buf)
    time.sleep(0.002)
    buf &= WRITE_EN       # Make EN = 0
    bus.write_byte_data(MCP23017_ADDRESS, MCP23017_GPIOB, buf)
    # 输送A高4位
    buf = LIGHT_R | LIGHT_B | LIGHT_K
    bus.write_byte_data(MCP23017_ADDRESS, MCP23017_GPIOA, buf)
    time.sleep(0.002)
    buf &= WRITE_EN       # Make EN = 0
    bus.write_byte_data(MCP23017_ADDRESS, MCP23017_GPIOA, buf)

def send_command(comm:int)->None:
    send_bit8(comm, "cmd")
    
def send_data(data:int)->None:
    send_bit8(data, "data")